#include <stdio.h>
#include <ctype.h>
#include <string.h>

#define KEY 6
char *keyword[KEY] = {"for", "if", "then", "else", "while", "do"};
char id[1024];
int num = 0;
int token;

int i = 0;

int charnum = 0;
char temp[10] = {'\0'};

void lexical(FILE *fp) {
	char x = getc(fp);

	num = 0;
	strcpy(id, "\0");

	//process x
	//process each regex here
	//store the result in global variables id, num, or token
	//in case of backtrack, use
	//ungetc(x, fp);

	switch(x)
	{
		case '\n':
		case '\t':
		case ' ':token = 1; break;
		case '+':token = 13; strcpy(id, "+"); break;
		case '-':token = 14; strcpy(id, "-"); break;
		case '*':token = 15; strcpy(id, "*"); break;
		case '/':token = 16; strcpy(id, "/"); break;
		case '=':token = 25; strcpy(id, "="); break;
		case ';':token = 26; strcpy(id, ";"); break;
		case '(':token = 27; strcpy(id, "("); break;
		case ')':token = 28; strcpy(id, ")"); break;
		case '#':token = 0; strcpy(id, "#"); break;
		case ':':
		temp[0] = getc(fp);
		if(temp[0] != '=')
		{
			token = 17;
			strcpy(id, ":");
			ungetc(temp[0], fp);
		}
		else
		{
			token = 18;
			strcpy(id, ":=");
		}
		fp--;
		break;
		case '<':
		temp[0] = getc(fp);
		if(temp[0] == '>')
		{
			token = 21;
			strcpy(id, "<>");
		}
		else if(temp[0] == '=')
		{
			token = 22;
			strcpy(id, "<=");
		}
		else
		{
			token = 20;
			strcpy(id, "<");
			ungetc(temp[0], fp);
		}
		fp--;
		break;
		case '>':
		temp[0] = getc(fp);
		if(temp[0] == '=')
		{
			token = 24;
			strcpy(id, ">=");
		}
		else
		{
			token = 23;
			strcpy(id, ">");
			ungetc(temp[0], fp);
		}
		fp--;
		break;
	case 'f'://here
	charnum = 0;
	temp[charnum] = 'f';//here
	while(temp[charnum] == keyword[0][charnum])//here
	{
		charnum++;
		temp[charnum] = getc(fp);
		if(charnum == 3)//here
		{
			if(temp[charnum] == ' ' || temp[charnum] == '(')
			{
				token = 1;//here
				strcpy(id, "for");//here
				ungetc(temp[charnum], fp);
				break;
			}
			else
			{
				while(temp[charnum] != ' ')
				{
					charnum++;
					temp[charnum] = getc(fp);
				}
				ungetc(temp[charnum], fp);
				temp[charnum] = '\0';
				break;
			}
		}
	}
	if(charnum == 3)//here
		break;
	else
	{
		token = 10;//here
		strcpy(id, temp);
		break;
	}
	

	case 'i'://here
	charnum = 0;
	temp[charnum] = 'i';//here
	while(temp[charnum] == keyword[1][charnum])//here
	{
		charnum++;
		temp[charnum] = getc(fp);
		if(charnum == 2)//here
		{
			if(temp[charnum] == ' ' || temp[charnum] == '(')
			{
				token = 2;//here
				strcpy(id, "if");//here
				ungetc(temp[charnum], fp);
				break;
			}
			else
			{
				while(temp[charnum] != ' ')
				{
					charnum++;
					temp[charnum] = getc(fp);
				}
				ungetc(temp[charnum], fp);
				temp[charnum] = '\0';
				break;
			}
		}
	}
	if(charnum == 2)//here
	{
		break;
	}
	else
	{
		token = 10;
		strcpy(id, temp);
		break;
	}
	case 't'://here
	charnum = 0;
	temp[charnum] = 't';//here
	while(temp[charnum] == keyword[2][charnum])//here
	{
		charnum++;
		temp[charnum] = getc(fp);
		if(charnum == 4)//here
		{
			if(temp[charnum] == ' ' || temp[charnum] == '(')
			{
				token = 3;//here
				strcpy(id, "then");//here
				ungetc(temp[charnum], fp);
				break;
			}
			else
			{
				while(temp[charnum] != ' ')
				{
					charnum++;
					temp[charnum] = getc(fp);
				}
				ungetc(temp[charnum], fp);
				temp[charnum] = '\0';
				break;
			}
		}
	}
	if(charnum == 4)//here
		break;
	else
	{
		token = 10;
		strcpy(id, temp);
		break;
	}
	case 'e'://here
	charnum = 0;
	temp[charnum] = 'e';//here
	while(temp[charnum] == keyword[3][charnum])//here
	{
		charnum++;
		temp[charnum] = getc(fp);
		if(charnum == 4)//here
		{
			if(temp[charnum] == ' ' || temp[charnum] == '(')
			{
				token = 4;//here
				strcpy(id, "else");//here
				ungetc(temp[charnum], fp);
				break;
			}
			else
			{
				while(temp[charnum] != ' ')
				{
					charnum++;
					temp[charnum] = getc(fp);
				}
				ungetc(temp[charnum], fp);
				temp[charnum] = '\0';
				break;
			}
		}
	}
	if(charnum == 4)//here
		break;
	else
	{
		token = 10;//here
		strcpy(id, temp);
		break;
	}
	case 'w'://here
	charnum = 0;
	temp[charnum] = 'w';//here
	while(temp[charnum] == keyword[4][charnum])//here
	{
		charnum++;
		temp[charnum] = getc(fp);
		if(charnum == 5)//here
		{
			if(temp[charnum] == ' ' || temp[charnum] == '(')
			{
				token = 5;//here
				strcpy(id, "while");//here
				ungetc(temp[charnum], fp);
				break;
			}
			else
			{
				while(temp[charnum] != ' ')
				{
					charnum++;
					temp[charnum] = getc(fp);
				}
				ungetc(temp[charnum], fp);
				temp[charnum] = '\0';
				break;
			}
		}
	}
	if(charnum == 5)//here
		break;
	else
	{
		token = 10;//here
		strcpy(id, temp);
		break;
	}
	case 'd'://here
	charnum = 0;
	temp[charnum] = 'd';//here
	while(temp[charnum] == keyword[5][charnum])//here
	{
		charnum++;
		temp[charnum] = getc(fp);
		if(charnum == 2)//here
		{
			if(temp[charnum] == ' ' || temp[charnum] == '(')
			{
				token = 6;//here
				strcpy(id, "do");//here
				fp--;
				break;
			}
			else
			{
				while(temp[charnum] != ' ')
				{
					charnum++;
					temp[charnum] = getc(fp);
				}
				ungetc(temp[charnum], fp);
				temp[charnum] = '\0';
				break;
			}
		}
	}
	if(charnum == 2)//here
		break;
	else
	{
		token = 10;//here
		strcpy(id, temp);
		break;
	}
	case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9':
	num = 0;
	temp[0] = x;
	charnum = 0;
	while(temp[charnum]<='9' && temp[charnum]>='0')
	{
		charnum++;
		temp[charnum] = getc(fp);

	}
	ungetc(temp[charnum], fp);
	for(;charnum>0;charnum--)
	{
		num = num*10;
		num = num + temp[charnum-1] - '0';
	}
	token = 11;
	break;
	default:
	charnum = 0;
	temp[0] = x;

	while((temp[charnum]<='9' && temp[charnum]>='0')||(temp[charnum]<='z' && temp[charnum]>='a')||(temp[charnum]<='Z' && temp[charnum]>='A'))
	{
		charnum++;
		temp[charnum] = getc(fp);

	}
	ungetc(temp[charnum], fp);
	temp[charnum] = '\0';
	token = 10;
	strcpy(id, temp);
	break;
}
}

int main(int argc, const char *argv[])
{
	if(argc < 2) {
		printf("insufficient args\n");
		return 1;
	}
	FILE *fp = fopen(argv[1], "r");
	do {
		lexical(fp);
		switch(token) {
			case 10: printf("(id, %s)\n", id); break;
			case 11: printf("(num, %d)\n", num); break;
			case -1: printf("error!\n"); break;
			case 1: break;
			default: printf("(%d, %s)\n", token, id);
		}
	} while(token != 0);
	fclose(fp);
	return 0;
}
